#ifndef _EVALUATE_H
#define _EVALUATE_H

#include "backend.h"

struct evaluate_result {
	int context;

	int type;

	union {
		struct {
			bool boolean;
		} boolean;

		struct {
			int integer;
		} integer;

		struct {
			int elemindex;
		} enum_basic;

		struct {
			int *elemindice;
		} enum_combo;

		struct {
			struct container *container;
		} container;

		struct {
			void *array;
		} array;
	} spec;

	void *location;	/* available for l-value */
};

void evaluate(struct evaluate_result *, struct expression *, struct access_table *, int);
void evaluate_assign(struct evaluate_result *, struct evaluate_result *);
void evaluate_function(struct evaluate_result *, int, int, struct expression *, struct access_table *, int);
void evaluate_identifier(struct evaluate_result *, char *, struct access_table *, int);
void evaluate_array_element(struct evaluate_result *, char *, struct expression *, struct access_table *, int);
void evaluate_location(struct evaluate_result *, void *, int);
void evaluate_numeric_binop(struct evaluate_result *, enum expression_cate, struct expression *, struct expression *, struct access_table *, int);
void evaluate_numeric_unop(struct evaluate_result *, enum expression_cate, struct expression *, struct access_table *, int);
void evaluate_convert(struct evaluate_result *, int);

int evaluate_int(struct expression *, struct access_table *, int);

void evaluate_enum_random(struct evaluate_result *r, enum type_cate, int, struct access_table *, int);
void evaluate_enum_extract(struct evaluate_result *, struct expression *, struct expression *, struct access_table *, int);
void evaluate_enum_combine(struct evaluate_result *, int, struct expression *, struct access_table *, int);

#endif
